package character {
	import org.flixel.plugin.photonstorm.FlxCollision;
	import org.flixel.FlxObject;
	import org.flixel.plugin.photonstorm.FlxVelocity;
	import states.GamePlayState;
	import org.flixel.FlxPoint;
	import org.flixel.FlxG;
	import org.flixel.FlxSprite;
	/**
	 * @author NilsIH
	 */
	public class Human extends FlxSprite{
		
		[Embed(source="../img/mannen.png")] private var ManWalks : Class;
		[Embed(source="../img/mann_fx.png")] private var ManFX : Class;
		[Embed(source="../img/ambulans.png")] private var Ambulans:Class;
		
		private var _direction:FlxPoint = new FlxPoint();
		private var _timeRemaining:Number = 0;
		private var doRandomMovement:Boolean = true;
		private var _humanToHelp:Human;
		private var _injured:Boolean;
		private var _carryingHuman:Boolean;
		private var _doTimedRefresh:Boolean;
		private var _isBurning:Boolean;
		private var _isInfested:Boolean;
		private var _isEaten:Boolean;
		private var _burningTimer:Number;
		public var damagePerSecond:Number = 4;
		private var _targetPoint:FlxPoint;
		private var _disappearTime:Number;
		
		public function get humanBeingCarried():Human {
			return _carryingHuman ? _humanToHelp : null;
		}
		
		public var speed:Number = 100;
		public var burningSpeed:Number = 200;
		public var zombieSpeed:Number = 40;
		public var type:String;
		
		public function Human(X:Number = 0, Y:Number = 0, SimpleGraphic:Class = null){
			super(X, Y, SimpleGraphic);
			addAnimationCallback(animcb);
		}
		
		override public function reset(X:Number, Y:Number):void {
			super.reset(X, Y);
			this._humanToHelp = null;
			doRandomMovement = false;
			_doTimedRefresh = false;
			_injured = false;
			_isBurning = false;
			_isInfested = false;
			_carryingHuman = false;
			visible = true;
			this.acceleration.x = 0;
			this.acceleration.y = 0;
			this.velocity.x = 0;
			this.velocity.y = 0;
		}
		
		public function initializeAs(type:String):void {
			this.type = type;
			
			if (type == "Regular"){
				loadGraphic(ManWalks, true, true, 56, 56);
				offset.x = 0;
				offset.y = 0;
				addAnimation("walk", [14, 15, 16, 17, 18, 19, 20], 8);
				addAnimation("firerun", [0, 1, 2, 3], 8);
				addAnimation("zombietransform", [4, 5, 6, 7, 8, 8], 8, false);
				addAnimation("zombiewalk", [9, 10, 11, 12], 8);
				play("walk");
				
				health = 10;
				doRandomMovement = true;
			}
			else if (type == "Hospital"){
				loadGraphic(Ambulans, true, true, 64, 40);
				addAnimation("amburunnormal", [4, 5, 6, 7], 8);
				addAnimation("amburunnwithpatient", [0, 1, 2, 3], 8);
				play("amburunnormal");
				health = 20;
			}
			
			_timeRemaining = timeUntilDirChange;
			revive();
		}
		
		public function goHelp(human:Human):void {
			_humanToHelp = human;
			this.refreshCourse();
		}
		
		public function refreshCourse():void{
			if (_carryingHuman){
				_targetPoint = GamePlayState.hospital.closestEntrance(this);
				FlxVelocity.moveTowardsPoint(this, _targetPoint, speed);
			}
			else if (_humanToHelp != null) FlxVelocity.moveTowardsObject(this, _humanToHelp, speed);
		}
		
		public function thrownOffCourse():void{
			_doTimedRefresh = true;
			_timeRemaining = 3;
		}
		
		public function reachedHuman():void{
			_humanToHelp.visible = false;
			_carryingHuman = true;
			play("amburunnwithpatient");
			refreshCourse();
		}
		
		public function reachedHospital():void {
			GamePlayState.hospital.beginTreatingHuman(_humanToHelp);
			GamePlayState.hospital.removeWorkerFromField();
			kill();
		}
		
		public function goRepair():void {
			
		}
		
		override public function update():void {
			super.update();
			
			if (type == "Regular"){
				facing = velocity.x < 0 ? FlxObject.RIGHT : FlxObject.LEFT;
				if (doRandomMovement){
				_timeRemaining -= FlxG.elapsed;
				if (_timeRemaining <= 0){
					changeDirection();
				}
			}
			}
			/*
			else if (type == "Hospital"){
				facing = velocity.x < 0 ? FlxObject.LEFT : FlxObject.RIGHT;
				if (_humanToHelp != null) {
					if (_carryingHuman){
						_humanToHelp.x = this.x + 3;
						_humanToHelp.y = this.y + 4;
						if (this.overlapsPoint(_targetPoint)) {
							reachedHospital();
						}
					}
					else {
						if (this.overlaps(_humanToHelp)){
							if (FlxCollision.pixelPerfectCheck(_humanToHelp, this)){
								reachedHuman();
							}
						}
					}
				}
				if (_doTimedRefresh){
					_timeRemaining -= FlxG.elapsed;
					if (_timeRemaining <= 0){
						refreshCourse();
						_doTimedRefresh = false;
					}
				}
			}
			 * 
			 */
			if (_isBurning){
				_burningTimer -= FlxG.elapsed;
				//changeDirection();
				if (_burningTimer <= 0){
					_isBurning = false;
					loadGraphic(ManFX, true, true, 56, 48);
					frame = 7;
					GamePlayState.applyScore("human", x, y);
					injured();
				}
			}
			
			if (_injured){
				_disappearTime -= FlxG.elapsed;
				if (_disappearTime <= 0){
					GamePlayState.killSprite(this);
				}
			}
			
			
		}
		
		public function changeDirection():void {
			if (alive)
			{
				var x:Number = (FlxG.random() * 2) - 1;
				var y:Number = (FlxG.random() * 2) - 1;
				var sum:Number = Math.abs(x) + Math.abs(y);
				_direction.x = x / sum;
				_direction.y = y / sum;
				
				if (_isBurning){
					velocity.x = _direction.x * burningSpeed;
					velocity.y = _direction.y * burningSpeed;
				}
				else if (_isInfested){
					if (NiloUtils.numberIsOver(.3)){
						moveTowardsHospital();
					}
					else {
						velocity.x = _direction.x * zombieSpeed;
						velocity.y = _direction.y * zombieSpeed;
					}
				}
				else {
					velocity.x = _direction.x * speed;
					velocity.y = _direction.y * speed;	
				}
				_timeRemaining = timeUntilDirChange;
			}
		}
		
		public function runOver():void {
			/*
			if (type == "Hospital"){
				GamePlayState.hospital.removeWorkerFromField();
				GamePlayState.applyScore("hospital", x, y);
				kill();
			}
			 * 
			 */
			 //FlxG.play(AssetStore.Hit3, .3);
			if (!_injured){
				loadGraphic(ManFX, true, true, 56, 48);
				addAnimation("hit", [0, 1, 2, 3, 4, 5, 6], 8, false);
				play("hit");
				offset.y = 10;
				GamePlayState.applyScore("humanhitbycar", x, y);
				injured();
			}
		}
		
		public function injured():void {
			_injured = true;
			doRandomMovement = false;
			velocity.x = 0;
			velocity.y = 0;
			_disappearTime = 3;
			/*
			if (_humanToHelp != null){
				GamePlayState.needToBeFetched(_humanToHelp);	
				_humanToHelp = null;
				GamePlayState.hospital.removeWorkerFromField();
			}
			 * */
			//GamePlayState.needToBeFetched(this);
		}
		
		public function get isBurning():Boolean {
			return _isBurning;
		}
		
		public function get isInjured():Boolean{
			return _injured;
		}
		
		public function get isInfested():Boolean{
			return _isInfested;
		}
		
		public function burn():void {
			if (!_isBurning && type != "Hospital"){
				
				
				FlxG.play(AssetStore.Hyl3, .3);
				play("firerun");
				_isBurning = true;
				_burningTimer = 2;
				
			}
		}
		
		public function infest():void {
			if (!_isInfested && type != "Hospital"){
				FlxG.play(AssetStore.Hyl1, .3);
				play("zombietransform");
				_isInfested = true;
				doRandomMovement = false;
				velocity.x = 0;
				velocity.y = 0;
			}
		}
		
		public function waitForBeingEaten():void{
			velocity.x = 0;
			velocity.y = 0;
			doRandomMovement = false;
			frame = 4;
		}
		
		public function eat():void {
			loadGraphic(ManFX, true, true, 56, 48);
			FlxG.play(AssetStore.plantespis);
			velocity.x = 0;
			velocity.y = 0;
			_injured = true;
			addAnimation("devoured", [8, 9, 10, 11, 12, 13, 14], 8, false);
			frame = 8;
			play("devoured");
			offset.y = 10;
			doRandomMovement = false;
		}
		
		
		
		public function moveTowardsHospital():void {
			FlxVelocity.moveTowardsPoint(this, GamePlayState.hospital.closestEntrance(this), zombieSpeed);
		}
		
		private function get timeUntilDirChange():Number {
			return 2 + (FlxG.random() * 2);
		}
		
		public function accelerateTo(X:Number, Y:Number, Time:Number):void {
			
		}
		
		public function animcb(name:String, frameN:Number, frameI:Number):void{
			if (name == "zombietransform") {
				if (frameN == 5){
					play("zombiewalk");
					doRandomMovement = true;
					changeDirection();		
				}
			}
			else if (name == "devoured") {
				if (frameI == 14){
					GamePlayState.applyScore("humandevoured", x, y);
					GamePlayState.killSprite(this);
				}
			}
		}
	}
}
